home *** CD-ROM | disk | FTP | other *** search
- //-------------------------------------------------------------------//
- // roots
-
- // Syntax: roots(P)
-
- // Description:
-
- // Find roots of polynomial P of degree n.
- //
- // Case 1:
- // P is a vector (row or column) with n+1 components representing
- // polynomial coefficients in descending powers.
- //
- // Case 2:
- // P is a linked-list of n+1 square matrices, the n+1 matrices in P
- // representing polynomial coefficients in descending powers.
- //
- // Return a column vector containing roots of P.
-
- // Example 1:
- // The following script finds the roots of
- // x^3 + 3*x^2 + 5 = 0
- //
- // > p=[1,3,0,5]
- // p =
- // 1 3 0 5
- // > r=roots(p)
- // r =
- // 0.213 - 1.19i
- // 0.213 + 1.19i
- // -3.43 + 0i
- // > q=<<1;3;0;5>>;
- // > r=roots(q)
- // r =
- // 0.213 - 1.19i
- // 0.213 + 1.19i
- // -3.43 + 0i
- //
- // Example 2:
- // Find the damped and undamped frequencies of the following oscillation
- // system:
- // 2
- // d u du
- // M --- + C -- + K u = 0
- // 2 dt
- // dt
- //
- // where M = 5 0.5 C = 5 1 K = 50 10
- // 0.5 5 1 5 10 50
- //
- // The characteristic equation corresponding to the governing equation
- // is
- // M*s^2 + C*s + K = 0
- //
- // > M=[5,0.5;0.5,5]; C=[5,1;1,5]; K=[50,10;10,50];
- // > // undamped frequencies
- // > uf = roots(<<M;zeros(2,2);K>>)
- // > uf =
- // > -3.97e-16 - 2.98i
- // > -3.97e-16 + 2.98i
- // > 2.84e-16 - 3.3i
- // > 2.84e-16 + 3.3i
- // The undamped vibration frequencies are 2.98 and 3.3 rad/s.
- // > // damped frequencies
- // > df = roots(<<M;C;K>>)
- // > df =
- // > -0.444 - 2.95i
- // > -0.444 + 2.95i
- // > -0.545 - 3.26i
- // > -0.545 + 3.26i
- // So we know the damped vibration frequencies are 2.95 and 3.26 rad/s.
- //
- // Example 3:
- // Same as Example 2, but C = 35 5
- // 5 35
- //
- // > M=[5,0.5;0.5,5]; C=[35,5;5,35]; K=[50,10;10,50];
- // > f = roots(<<M;C;K>>)
- // > f =
- // -5.16
- // -4.82
- // -2.12
- // -1.84
- // All roots are negative real ===> no oscillation but stable.
-
- // See Also: poly
-
- // Tzong-Shuoh Yang
- // (tsyang@ce.berkeley.edu) 5/7/94 scalar polynomial roots
- // 3/2/95 matrix polynomial roots
- //
- //-------------------------------------------------------------------//
- roots = function(P)
- {
- local(P);
-
- if (class(P) == "num") {
- // scalar polynomial
- if (P.n <= 1) {
- error("Argument of roots() is a scalar, not a polynomial.");
- else if (min(size(P)) != 1) {
- error("Argument of roots() must be a column or a row vector.");
- }}
- p = P[:]';
- // trim leading and trailing zeros
- z = find(p != 0);
- nz = p.n - z[z.n];
- p = p[z[1]:z[z.n]];
- // find companion matrix
- c = compan(p);
- else if (class(P) == "list") {
- // matrix polynomial
- n = max(strtod(members(P)));
- if (n <= 1) {
- error("Argument list of roots() is not a matrix polynomial.");
- }
- ns = P.[1].nr;
- if (ns != P.[1].nc) {
- error("Argument list components of roots() must be square matrices.");
- }
- for (i in 2:n) {
- if (P.[i].nr != ns || P.[i].nc != ns) {
- error("Argument list components of roots() must be the same size.");
- }
- }
- // find leading and trailing zero matrices
- z = [];
- for ( i in 1:n) {
- if (any((P.[i] != 0)[:])) {
- z = [z,i];
- }
- }
- nz = (n - z[z.n])*ns;
- // find companion matrix c
- n0 = z[1];
- n1 = z[z.n];
- P.[n0] = factor(P.[n0],"g");
- for (i in (n0+1):n1) {
- P.[i] = -backsub(P.[n0], P.[i]);
- }
- n2 = (n1-n0)*ns;
- c = zeros(n2,n2);
- for (i in 1:(n2-ns)) {
- c[i;ns+i] = 1;
- }
- j = (n2-ns+1):n2;
- k = j;
- for(i in (n0+1):n1) {
- c[j;k] = P.[i];
- k = k - ns;
- }
- else {
- error("Wrong argument class in roots().");
- }}}
- // find roots and stuff with trailing zero(s)
- r = [zeros(nz,1);eign(c).val'];
- // trim complex part if all real
- if (all(imag(r) == 0)) {
- r = real(r);
- }
- // if you don't want the roots sorted in ascending order,
- // comment out the next line
- r = sort(r).val;
- return r;
- };
-